import { Effect, Fiber } from "effect";

//         ┌─── Represents the success type
//         │        ┌─── Represents the error type
//         │        │
//         ▼        ▼
// Fiber<Success, Error>

const fib = (n: number): Effect.Effect<number> =>
  n < 2
    ? Effect.succeed(n)
    : Effect.zipWith(fib(n - 1), fib(n - 2), (a, b) => a + b);

// fork 产出一个 Fiber
//      ┌─── Effect.Effect<Fiber.RuntimeFiber<number, never>, never, never>
//      ▼
const fib10Fiber = Effect.fork(fib(10));

// 合并一个 Fiber
const program = Effect.gen(function* () {
  // Retrieve the fiber
  const fiber = yield* fib10Fiber;
  // Join the fiber and get the result
  const n = yield* Fiber.join(fiber);
  console.log(n);
});

Effect.runFork(program); // Output: 55
